"""
@-*- coding: utf-8 -*-
@ python：python 3.8
@ 创建人员：ylx
@ 创建时间：2025/2/21 上午11:35
@ 内容：
"""
"""
如果你新建一个项目想通过git来管理，那么你首先本地需要安装git,安装完成后进入
你这个项目的文件夹，右键选择git bash here 开始使用git命令，初步安装完成后，需要配置
你的username和password，可以百度 https://blog.csdn.net/weixin_62300611/article/details/142148390
一般这些你可以在你的gitee新建仓库后，可以有相关的本地仓库配置引导

进入文件夹后开始使用命令
git init 初始化你的项目成为一个标准的git 仓库
git add 文件名称  或者git add . 将你的文件先添加至暂存区
git commit -m '本次提交说明' 这时你相关文件已经被提交到默认的master分支

我们如果要区分分支来管理项目
git checkout -b dev 创建并切换至dev分支，这个分支是基于master分支创建的，所以内容也都还是原有master分支的

我们此时的开发均是在dev分支上进行，操作完成后

git checkout -b qa dev 创建并切换至QA分支，QA分支的代码是基于dev分支的

测试完成后 切换至release分支
git checkout -b release qa

准备发布版本时，此时我们合并至master分支
git checkout master 切换至master分支
git merge release 



git branch 查看分支状态
git log --oneline --graph --all 查看所有分支及历史提交记录



如果你是访问别人的项目，并且基于此来开发，那你进入希望存放项目的目录后，首先远程克隆这个仓库
git clone 远程仓库的url
cd 项目名称

克隆仓库后，你可以先查看远程仓库中有哪些分支   git  branch -r

但是开发时，若你要在dev 分支开发，但你必须从远程分支创建并切换至本地分支
git checkout -b dev origin/dev
这条命令的作用是从远程的dev分支创建一个本地的dev分支，并切换至本地dev分支

如果你的本地已经有一个dev分支，那么你可以直接切换他即可  git checkout dev

git branch 确认你是否在目标分支，前面会有*的表明你当前所在的分支

完成开发后你需要
git add .
git commit -m '开发说明'

推送至远程分支
git push origin dev

如果远程仓库没有dev分支，你可以从默认分支，如master创建一个新的dev分支
git checkout -b dev
然后将新建的dev分支推送至远程仓库
git push -u origin dev

你在推送你项目的代码之前必须要先拉取远程仓库的内容并合并
git pull origin master,然后再次推送，避免相关的合并冲突，你要拉取你要推送的目标分支的最新代码


实际项目中，你需要clone别人的仓库，并基于此进行开发，那你拉下来的仓库是否含有这4个分支，又或者你该如何开发呢？
一般来说当你克隆一个远程仓库时，默认情况下只会检出远程仓库的默认分支，比如说master，但是所有远程分支的信息会下载至本地
git clone  url后  git branch 通常只会看到一个本地的分支

使用git branch -r 查看远程分支
你在克隆后想切换至其它分支，首先你可以
git checkout dev   检查是否存在本地分支dev  若不存在，则远程分支的origin/dev 创建一个本地的dev分支，切换至本地分支

你也可以直接明确的指定从远程分支创建本地分支
git checkout -b dev origin/dev

一般来说克隆后只有默认分支会被检测为本地分支
如果你想克隆摸个特定的分支，使用--branch
git clone -b dev url  虽然你指定了分支，但是远程仓库的其他分支信息仍然会被下载至本地

在git中origin是一个默认的远程仓库的别名，不代表你项目的名称，你在日常使用时不需要将origin替换为项目名称，可以直接使用origin
这个就是在你第一次git clone时git 会自动化将远程仓库命名为origin



git remote add origin url  将远程仓库地址添加到本地仓库，也就是说让本地仓库和远程仓库关联起来


你首次推送时，如果你还没有基于分支管理，你的本地和远程都应该是master分支
首次推送使用 git push  -u origin master 这个命令首先会清楚的指定要推送的分支是master
其次通过-u 参数git会将本地分支与远程分支关联起来，后续可以直接使用git push 而不需要指定分支
你如果使用这个的话，git branch -vv查看分支是否已关联
如果输出展示 * master    【origin/master】   那就说明本地的分支master 已经和远程的origin/master关联

推荐最佳实践
为了减少冲突的一致性，克隆仓库或者切换分支后，先运行git pull ,确保本地分支是最新的
完成本地开发后，先提交自己的更改，然后再git pull
解决相关冲突，然后
再次推送之前 先git pull   再git push

git pull的本质是git fetch   git merge  获取远程仓库的最新更烦，但是不合并到你的本地分支+将远程分支的更改合并到当前分支




我远程仅有master，我clone后，本地开始基于dev qa release 管理，我该如何保证远程仓库也根据分支管理

git checkout -b release 从当前分支新建release并切换
git checkout -b release qa 从指定的qa分支新建分支release并切换

分支合并后 只是将dev分支上的更改应用到了master分支上，dev本身还是存在的
删除本地分支使用 git branch -d dev
删除远程分支  git push origin --delete dev


推送分支到远程仓库，不需要先切换至这个分支可以直接
git push origin dev   比如你现在在master分支工作，但是希望推送dev分支到远程仓库，可以直接运行

综上问题，你必须要先本地创建 dev qa release ，
执行git checkout -b dev 创建并切换到dev分支
执行git checkout -b qa 创建并切换到qa分支
执行git checkout -b release 创建并切换到release分支  这些命令都是基于你当前分支来创建的

此时你为了让远程仓库拥有这些分支，你可以直接
git push -u origin dev
git push -u origin qa
git push -u origin release

通过git branch -r查看远程仓库的分支

此时你本地的分支和远程分支已经完成
使用命令切换分支进行开发-git checkout dev
然后进行暂存  提交，拉取 推送

然后你dev分支完成后，现在开始本地可以推送至qa分支
git checkout qa
git merge dev


git config user.name 单独查看用户名
git config user.email 单独查看邮箱
git config --global --list 查看全局配置
git config --list 查看当前项目配置
git remote -v 查看远程仓库地址



使用git merge的场景，你目前在feature分支开发，完成后想合并至主分支并推送至远程主分支
那你必须
先切换至主分支 git checkout main
拉取主分支最新代码 git pull origin main
合并特性分支至主分支 git merge feature 
合并后，推送更新后的主分支到远程仓库 git push origin main


使用git rebase 场景，假设开发工作流同上
rebase允许你在特性分支上逐步解决冲突，而不是等最后合并时一次性处理所有的冲突
首先切换至特性分支 git checkout feature
变基到主分支 git rebase main 这会将feature分支的提交重新应用到main分支的最新提交之上
完成变基后，切换主分支 git checkout main
快速合并特性分支-因为已经完成了变基，现在可以快速合并 git merge feature
推送更新后的主分支到仓库 git push origin main


不要对已推送的分支执行 rebase：
如果你的特性分支已经推送到远程仓库，并且其他人可能基于它进行开发，那么执行 rebase 会导致问题。因为 rebase 改变了提交历史，远程仓库和本地仓库之间的提交历史会不一致。
强制推送：
如果你已经对特性分支执行了 rebase 并且需要推送到远程仓库，你需要使用 git push --force 或 git push --force-with-lease 来覆盖远程分支的历史。
适合个人分支：
rebase 更适合在个人开发的特性分支上使用，而不是团队协作的共享分支。

在特性分支 feature上执行git rebase 是否会影响主分支的提交历史？
当你在特性分支上执行 git rebase main 时，这一操作不会直接影响主分支的历史
这是因为 rebase 操作是在特性分支上进行的，它将特性分支上的提交重新应用到主分支最新的提交之上，从而使得特性分支包含了所有主分支的更新，并且保持了线性的历史记录。

具体影响如下：
特性分支：特性分支的历史会被重写，其提交会基于主分支最新的提交重新创建。这意味着特性的提交将会获得新的哈希值，并且看起来像是直接在最新的主分支基础上开发的一样。
主分支：此时主分支的历史并没有受到影响。只有当你随后切换回主分支并将特性分支合并（或变基后的特性分支）推送到主分支时，才会改变主分支的历史。
如何影响主分支历史？
使用 git merge：
如果你在主分支上执行 git merge feature-branch 来合并经过变基的特性分支，这会在主分支上生成一个新的合并提交（除非可以快速前进），但是不会改变已经存在于主分支上的提交历史。
使用 git rebase 然后 git merge --ff-only 或快进合并：
如果你希望避免额外的合并提交并且特性分支是基于最新主分支的，则可以直接使用 git merge --ff-only，这样只会移动主分支指针而不会创建新的合并提交，因此主分支的历史看起来就像所有的提交都是顺序发生的。
直接在主分支上执行 git rebase：
不推荐直接在共享分支如主分支上执行 git rebase，因为这会改写该分支的历史，可能会对其他开发者造成困扰。
总结
在特性分支上执行 git rebase main 不会立即影响主分支的历史。主分支的历史只会在你实际将更改合并进入主分支时才可能发生变化。通过选择适当的合并策略（例如是否允许非快进合并），你可以控制主分支历史的变化方式。重要的是，在处理公共分支时要小心使用 rebase，以避免不必要的历史重写和冲突。

什么时候可以使用 rebase？

在个人开发的特性分支上，或者在未共享的分支上，可以使用 rebase 来保持提交历史的整洁。

假设你有一个特性分支 feature-branch，并将其推送到远程仓库。Bob 和 Alice 分别基于这个分支进行开发。

场景 1：你对 feature-branch 执行 rebase
你对 feature-branch 执行 git rebase main 并强制推送到远程仓库。
Bob 和 Alice 在本地仍然基于旧的 feature-branch 历史开发。
当他们尝试将自己的更改推送到远程仓库时：
Git 报错，提示他们的本地分支与远程分支的历史不一致。
他们需要手动解决冲突，甚至可能丢失部分工作。
场景 2：你对 feature-branch 使用 merge
你将 main 分支的更新合并到 feature-branch（使用 git merge main）。
Bob 和 Alice 继续基于远程的 feature-branch 开发。
没有任何冲突或历史不一致的问题，因为他们仍然基于相同的提交历史工作。
4. 为什么会这样？
核心原因是 rebase 的工作机制：

rebase 改写提交历史：它会重新创建提交，并赋予它们新的哈希值。这意味着旧的提交历史被“抛弃”了。
Git 的分布式特性：每个开发者在本地都有一个完整的代码库副本。如果远程分支的历史发生变化（例如通过 rebase 改写），本地副本与远程副本之间就会出现不一致。
5. 如何避免这些问题？
如果你确实需要对共享的特性分支执行 rebase，可以采取以下措施来减少影响：

(1) 提前沟通
在执行 rebase 和强制推送之前，通知所有基于该分支工作的开发者，提醒他们暂停开发或做好备份。
(2) 使用 --force-with-lease
使用 git push --force-with-lease 而不是 git push --force。--force-with-lease 会在推送前检查远程分支是否发生了变化，从而减少覆盖他人工作的风险。
(3) 优先使用 merge
对于共享分支，推荐使用 git merge 而不是 rebase。merge 不会改写提交历史，而是生成一个新的合并提交，保留完整的分支历史。
(4) 避免对公共分支使用 rebase
在团队协作中，尽量避免对公共分支（如 main、develop 等）执行 rebase。这些分支通常是多人协作的基础，改写历史会导致混乱。
6. 总结
特性分支未被共享时：你可以安全地使用 rebase，因为它只会影响你的本地环境。
特性分支被共享时：不要使用 rebase，因为它会改写提交历史，导致其他人基于旧历史的工作无法顺利同步到远程仓库。
为什么会有影响：因为 rebase 改写了提交历史（生成新的哈希值），破坏了其他人对旧历史的依赖关系。
通过遵循这些原则，可以有效避免因 rebase 引发的协作问题，同时保持代码库的整洁和可维护性。


git 命令

git commit 提交
git branch 创建新分支
git checkout 切换至目标分支
git checkout -b 创建并切换至目标分支

git merge  将非当前所在的分支 合并至当前所在的分支
git rebase 是你想将当前分支 往主分支线性合并时使用  操作时，当前在特性分支  然后再切回main 再将main rebase 到bugfix分支上即可
"""
